package com.yuedou.api.pay.nongshang;

import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class NSHUtils {

    /**
     * 验证回调签名
     * @param map
     * @return
     */
    public static boolean validateSignNSh(Map<String, String> map, String api_key)throws Exception  {
        String signFromAPIResponse = map.get("sign");
        if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
            System.out.println("API返回的数据签名数据不存在，有可能被第三方篡改!!!");
            return false;
        }
        //过滤空 设置 TreeMap
        SortedMap<String,String> packageParams = new TreeMap<>();
        for (String parameter : map.keySet()) {
            String parameterValue = map.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = URLDecoder.decode(parameterValue.trim()) ;
            }
            packageParams.put(parameter, v);
        }

        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if(!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        String toBeSign = sb.toString();
        toBeSign = toBeSign.substring(0,toBeSign.length() - 1);
        toBeSign += api_key;

        //将API返回的数据根据用签名算法进行计算新的签名，用来跟API返回的签名进行比较
        //算出签名
        System.out.println("计算签名的数据：" + toBeSign);
//        byte[] localSignature = hmacSHA256(toBeSign.getBytes(), api_key.getBytes());


        byte[] data = toBeSign.getBytes("UTF-8");
//        System.out.println("加密串:\n" + toBeSign);
        InputStream is = new ByteArrayInputStream(data);
        String bodyDigest = testSHA256(is);

//        String resultSign = Base64.encodeBase64String(localSignature);   // Signature
        String sign = packageParams.get("sign").toUpperCase();
        System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);
        //1671EB4CBEBE37BB5E2731F79EEF2CCAAE80774895A463DE0A6011A0EB9BC1F1
        //42b840333cefc4e22511a67493ff70bf1abdd55bb50c0fdcc2b8d939ca7f80f9
        System.out.println("计算出来的签名：" + bodyDigest);
        boolean bl = sign.equals(bodyDigest.toUpperCase());
        return bl;
    }


    /**
     * 进行加密
     *
     * @param is
     * @return 加密后的结果
     */
    private static String testSHA256(InputStream is) {
        try {
//            System.out.println(is.hashCode());
            return DigestUtils.sha256Hex(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) {
        String toBeSign = "attachedData=ELECTRIC_RECHARGE&bankInfo=OTHERS&billFunds=现金:1&billFundsDesc=现金支付0.01元。&buyerCashPayAmt=1&buyerId=otdJ_uAqAjrCYNK0bhMQvJBNLbsI&buyerPayAmount=1&cardAttr=BALANCE&connectSys=UNIONPAY&couponAmount=0&createTime=2022-09-11 20:46:50&FH=nngY&instMid=MINIDEFAULT&invoiceAmount=1&mchntUuid=2d9081bd82f8c1a5018310959f25381a&merName=跃豆智慧生活科技（山东）有限公司&merOrderId=32WT1662900409419&mid=8983711651302D6&msgType=wx.notify&notifyId=7019457c-df89-4b55-9ddc-4597e1118810&orderDesc=跃豆智慧生活科技（山东）有限公司&payTime=2022-09-11 20:46:57&receiptAmount=1&seqId=29563169337N&settleDate=2022-09-11&signType=SHA256&status=TRADE_SUCCESS&subBuyerId=o1BmO5LJipl9YmZuwdRS7uPxiN8c&subInst=100100&targetOrderId=4200001570202209112894347239&targetSys=WXPay&tid=8699CXK6&totalAmount=1&cYhkppAyM6afKAFWZJE4wMHdHCmFH8mTKt4EaY2YFJQYB88s";
//        toBeSign = URLDecoder.decode(toBeSign);
//        System.out.println("toBeSign: " + toBeSign);


//        农商行  支付回调：
//        {FH=nngY, msgType=wx.notify, payTime=2022-09-11 20:46:57, buyerCashPayAmt=1, connectSys=UNIONPAY, sign=136BC2A594B27B7FD20F640EEEAA3A9A7168547933FDD3B90394C7B5DC622380, merName=跃豆智慧生活科技（山东）有限公司, mid=8983711651302D6, invoiceAmount=1, settleDate=2022-09-11, billFunds=现金:1, buyerId=otdJ_uAqAjrCYNK0bhMQvJBNLbsI, mchntUuid=2d9081bd82f8c1a5018310959f25381a, tid=8699CXK6, instMid=MINIDEFAULT, receiptAmount=1, couponAmount=0, attachedData=ELECTRIC_RECHARGE, cardAttr=BALANCE, targetOrderId=4200001570202209112894347239, signType=SHA256, billFundsDesc=现金支付0.01元。, subBuyerId=o1BmO5LJipl9YmZuwdRS7uPxiN8c, orderDesc=跃豆智慧生活科技（山东）有限公司, seqId=29563169337N, merOrderId=32WT1662900409419, targetSys=WXPay, bankInfo=OTHERS, totalAmount=1, createTime=2022-09-11 20:46:50, buyerPayAmount=1, notifyId=7019457c-df89-4b55-9ddc-4597e1118810, subInst=100100, status=TRADE_SUCCESS}
//        计算签名的数据：



        byte[] data = new byte[0];
        try {
            data = toBeSign.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
//        System.out.println("加密串:\n" + toBeSign);
        InputStream is = new ByteArrayInputStream(data);
        String bodyDigest = testSHA256(is);
//        System.out.println("bodyDigest: " + bodyDigest);
    }

    /**
     * @param data
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key, algorithm));
        return mac.doFinal(data);
    }


}
